package com.warm.base.jdk.grammar;

import com.warm.common.entity.SysUser;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @Date: 2019/10/30 16:59
 * @Author: LChuang
 * @Description:
 */
public class ReflectTest {

    public static void main(String[] args) {
        try {
            //类是 java.lang.Class 的实例化对象
            SysUser sysUser = new SysUser();

            //任何一个类都有一个隐含的静态成员变量class
            Class c1 = SysUser.class;
            //已知了该类的对象的情况下通过getClass方法获取
            Class c2 = sysUser.getClass();
            //使用类加载器加载类
            Class c3 = Class.forName("com.warm.demo.entity.SysUser");

            //一个类只可能是 Class 类的一个实例对象
            System.out.println(c1==c2);
            System.out.println(c1==c3);

            //通过类的类类型创建该类的对象实例
            SysUser user = (SysUser) c1.newInstance();

            //方法的反射
            System.out.println(c1.getName());
            System.out.println(c2.getName());
            System.out.println(c2.getSimpleName());
            System.out.println(c3.getName());

            // **getMethods 获得所有 public 方法,包括父类继承的方法
            // **获取所有类自己声明的方法,使用 getDeclaredMethods(), 不管访问权限**
            Method[] ms = c1.getMethods();
            Map<String, Object> methodMaps = new HashMap<>();
            for (int i = 0; i < ms.length; i++) {
                Map<String, Object> mMap = new HashMap<>();
                //获取方法信息
                // 返回值
                Class returnType = ms[i].getReturnType();
                // 返回值类型名字
                String returnTypeName = returnType.getName();
                // 方法名
                String methodName = ms[i].getName();
                // 参数类型 --> 参数列表类型的类类型
                Class[] paramTypes = ms[i].getParameterTypes();
                StringBuilder params = new StringBuilder();
                for (Class clazz : paramTypes){
                    params.append(clazz.getName()).append(",");
                }
                mMap.put("returnTypeName", returnTypeName);
                mMap.put("methodName", methodName);
                mMap.put("params", params);
                methodMaps.put("mMap", mMap);
            }
            System.out.println(methodMaps.toString());

            //获得成员变量 getFields() -- public, getDeclaredFields() -- all
            Field[] fs = c1.getDeclaredFields();
            Map<String, Object> fieldMaps = new HashMap<>();
            for (Field field : fs){
                Map<String, Object> fMap = new HashMap<>();
                //成员变量类型的类类型
                Class fieldType = field.getType();
                String typeName = fieldType.getName();
                //得到成员变量的名称
                String fieldName = field.getName();
                fMap.put("typeName", typeName);
                fMap.put("fieldName", fieldName);
                fieldMaps.put("fMap", fMap);
            }
            System.out.println(fieldMaps.toString());

            //构造方法反射
            // getConstructors()方法获取所有的public的构造函数
            // getDeclaredConstructors()方法得到所有的自己声明的构造函数
            Constructor[] cs = c1.getDeclaredConstructors();
            for (Constructor c : cs) {
                //获取构造方法参数列表
                Class[] paramTypes = c.getParameterTypes();
            }

            //动态加载类

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

}
